import { _decorator, BoxCollider2D, Collider2D, Component, Contact2DType, find, game, IPhysics2DContact, misc, Node, PhysicsSystem2D, UITransform, v3, Vec3, view } from 'cc';
import { BulletLayers } from './BulletLayers';
import { BulletType, gameConfig } from './Configs';
import { Enemy } from './Enemy';
import { ModuleMgr } from './ModuleMgr';
import { ModuleBase } from './ModuleBase';
import { UIRoot } from './UIRoot';
const { ccclass, property } = _decorator;

@ccclass('Bullet')
export class Bullet extends Component {

    private _dir: Vec3 = v3();
    private _angleSpeed: number = 0;
    private _verAcc: number = 0;
    private _horAcc: number = 0;
    private _speedX: number = 0;
    private _speedY: number = 0;
    //获取地板的高度
    private _floorHeight: number = 0;
    private _bulletType: BulletType = BulletType.None;
    private _bulletLayersTs: BulletLayers = null;
    //初始化子弹的位置
    oninit(dir: Vec3, bulletType: BulletType) {
        this._bulletType = bulletType;
        this._floorHeight = find("Canvas/Game/GameFloor").getComponent(UITransform).height;
        this._dir = dir;
        this.radianToAngle();
        this._angleSpeed = gameConfig.fireSpeed;
        this._speedX = this._angleSpeed * this._dir.x;
        this._speedY = this._angleSpeed * this._dir.y;
        this._verAcc = gameConfig.verAcc;
        this._horAcc = gameConfig.horAcc;
        if (bulletType == BulletType.Enemy) {
            this._verAcc = 0;
            this._horAcc = 0;
        }
        //开启碰撞系统
        if (PhysicsSystem2D.instance) {
            PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onCollider, this);
        }

        let bulletLayersNode = this.node.parent;
        this._bulletLayersTs = bulletLayersNode.getComponent(BulletLayers);
    }

    onCollider(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        console.log(selfCollider.group);

        if (this._bulletType === BulletType.Player && otherCollider.group == 2) {
            //敌人死亡
            otherCollider.getComponent(Enemy).death();
            this._bulletLayersTs.sendMsg("updateScore", "Score");
            //将子弹从子弹容器中移除
            this.removeBulletFromArr();
            //子弹销毁,使用removeFromParent会导致内存泄漏
            this.node.destroy();
            //玩家移动
            this._bulletLayersTs.sendMsg("playerRun", "PlayerLayers");
        } else if (this._bulletType === BulletType.Enemy && otherCollider.group === 8) {
            //将子弹从子弹容器中移除
            this.removeBulletFromArr();
            //子弹销毁,使用removeFromParent会导致内存泄漏
            this.node.destroy();
            let playerNode = ModuleMgr.instance.getModule<ModuleBase>("PlayerLayers").node.getChildByName("Player");
            playerNode.destroy();
            UIRoot.instance.openUI("GameOver", "Window");
        }
    }


    //更新子弹的移动位置
    onUpdate(dt: number, ...rest: any[]) {
        this._speedX += this._horAcc * dt;
        this._speedY += this._verAcc * dt;
        let x = this.node.position.x;
        let y = this.node.position.y;
        x += this._speedX * dt;
        y += this._speedY * dt;
        this.node.setPosition(x, y, 0);
        //进行归一化处理可以只得到方向
        this._dir = v3(this._speedX, this._speedY).normalize();
        this.radianToAngle();
        this.isPassArea();
    }

    radianToAngle() {
        //将方向转换成弧度
        //参数1是起始向量，参数2是终止向量，参数3是旋转轴
        let radians = Vec3.signedAngle(v3(1, 0, 0), this._dir, v3(0, 0, 1));
        //将弧度转换成角度，并设置给子弹
        this.node.angle = misc.radiansToDegrees(radians);
    }

    isPassArea() {
        if (this.node.position.x >= view.getDesignResolutionSize().width
            || this.node.position.y <= this._floorHeight) {
            if (this._bulletType == BulletType.Player) {
                let playerNode = ModuleMgr.instance.getModule<ModuleBase>("PlayerLayers").node.getChildByName("Player");
                this._bulletLayersTs.sendMsg("enemyFire", "EnemyLayers", playerNode);
            }
            this.removeBulletFromArr();
            this.node.destroy();
        }
    }

    removeBulletFromArr() {
        for (let i = 0; i < this._bulletLayersTs.bulletArr.length; i++) {
            if (this === this._bulletLayersTs.bulletArr[i]) {
                this._bulletLayersTs.bulletArr.splice(i, 1);
            }
        }
    }
}


